home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-01-02 | 29.3 KB | 1,190 lines |
-
- ;get following box
-
- get_follow_box:
- mov ax,w box ;load follow box
- mov cx,ax ;save it
- mov bx,w follow_route ;load following route
- call get_box_par ;get box route of following box
- mov bx,ax
- mov ax,cx ;load following box
- call get_route ;get its box route of
- ret ;exit
-
- ;check if route is outstanding subchart route
-
- get_hor_stem:
- mov ax,w box_route ;load box route
- mov dx,ax ;save it
- call get_box_par ;get its route box
- cmp ax,dx ;is it a outstanding route?
- mov al,'?' ;load outstanding route character
- je ret ;create rest of route string
-
- ;get box of route
-
- mov di,o number_buffer ;load offset
- mov ax,': ' ;load separator
- stosw ;store it at start of buffer
- mov ax,dx ;get box of route
- mov bx,w[si] ;load element offset
- call get_route
- mov dx,ax ;save it
- sub ax,first_box-1 ;calculate box number
- call store_number2 ;convert it to string
- sub di,o number_buffer ;calculate size of string in buffer
- mov cx,di
-
- ;copy route path to start of descripter store
-
- mov di,o descripter_string ;load destination offset
- sub di,cx ;calculate offset to start of string
- mov bx,di ;save it
- push cx ;save count
- a1:
- std ;read backwards
- lodsb ;load character from start of buffer
- cld ;write forwards
- stosb ;store character at end of buffer
- loop a1 ;decrement loop count
-
- ;copy part or all of box route descripter string to buffer
-
- mov ax,dx ;load box of route
- call get_box_descripter ;get descripter string length and offset
- cmp cx,13 ;is it bigger than 13
- if a mov cx,13 ;load string size if it is
- pull dx ;restore count of path
- add dx,cx ;add it to descripter
- mov di,o descripter_string ;load offset to descripter buffer
- rep
- movsb ;copy string
- mov ds,ax,cs ;restore data segment register
- ret ;exit
-
- ;write trailing stem to screen with indicator string at top of stem
-
- connect:
- mov dx,w cursor_pos ;load cursor coordinates
- mov cx,5 ;calculate length of stem
- sub cx,w stem_start
- jcxz >b1 ;write bottom of stem character if nul
- add w cursor_pos+1,cx ;add count to cursor column
- call write_stem ;write stem to screen
-
- ;write bottom of stem character
-
- b1:
- mov al,'╨' ;load character
- call cursor ;position cursor
- inc dh ;move to next row
- mov w cursor_pos,dx ;save cursor position
- jmp write_chr ;write character and exit
-
- ;create subchart
-
- create_subchart:
- mov ax,w next_box ;load new box
- call make_box ;clear it
- es mov w[di+parent],bp ;make subcharts parent current box
- mov bx,child ;load element offset
- mov dx,w next_box ;make current box parent of subchart
- call store_current_box_par
-
- ;exit to chart loop
-
- and b box_made,1 ;indicate box created
- mov b chart_flag,2 ;set chart entry flag
- stc ;exit to chart loop
- ret
-
- ;check if subchart is copied
-
- down:
- mov b chart_flag,4 ;set chart entry flag
- down2:
- mov bx,child ;load child element offset
- call get_current_box_par ;get boxes child status
- mov dx,ax ;save subchart
- mov bx,parent ;load parent offset
- call get_box_par ;get parent of subchart
- cmp ax,bp ;is it current box?
- je >a1 ;goto subchart if it is
-
- ;push this level onto stack
-
- sub w sub_stack,4 ;increment stack pointer
- les di,w sub_stack ;load pointer to subchart stack
- xchg ax,bp ;load current box
- stosw ;store it in stack
- xchg ax,bp ;load return box
- stosw ;store it in stack
-
- ;move down a level
-
- a1:
- mov bp,dx ;make first box in subchart current box
- stc ;exit to chart loop
- ret
-
- ;move up to parent box from subchart
-
- up_option:
- mov b chart_flag,4 ;set chart entry flag
- mov bx,parent ;load element offset
- call get_current_box_par ;get parent of subchart
- les si,w sub_stack ;load pointer to subchart stack
- cmp si,top_stack ;is stack empty
- je >a1 ;get parent box if not
- es cmp w[si+2],ax ;is subchart copied?
- je >a2 ;copy its parent if it is
- a1:
- mov bp,ax ;make parent box current box
- stc ;exit to chart loop
- ret
-
- ;set current box as subchart step parent box
-
- a2:
- es mov bp,w[si] ;load box
- add w sub_stack,4 ;move up a level
- stc ;exit to start of chart loop
- ret
-
- ;end subchart option
-
- end_sub_option:
- cmp w key_option,14*2 ;has route been chosen from parent box?
- if e jmp long >b1 ;store route if it has
- mov b new_chart,0 ;indicate chart changed
- mov ax,w route ;save route select
- mov w subchart_route,ax
- mov ax,w current_route ;save current route offset
- mov w terminating_route,ax
- xor dx,dx ;clear route count
- mov bx,parent ;get parent of subchart
- call get_current_box_par
- mov si,ax ;save it
- call get_routes ;copy its routes
- mov bx,no ;load route offset
- mov w route,yes ;store route incase there arnt any
-
- ;count number of routes leading from parent box
-
- a1:
- mov w[bx+option_routes],0 ;clear extra route option
- mov ax,w[bx+routes] ;load box route
- cmp ax,1 ;is there a route?
- jbe >a2 ;decrement loop count if not
-
- ;copy route
-
- mov w route,bx ;save route
- inc dx ;increment route count
- mov b[bx+option_routes],1 ;add route option
- a2:
- sub bx,2 ;move to next route
- jne a1 ;decrement loop count
-
- ;make current box parent box
-
- mov w box_save,bp ;make main box current box
- mov link_box,bp ;make link box current box
- mov bp,si ;make current box parent box
- mov w key_option,14*2 ;set key option
- mov ax,w route ;copy first route
- mov w current_route,ax
-
- ;check if there is more than one route
-
- cmp dx,1 ;is there?
- jbe >b1 ;end subchart if not
- call create_link_string ;create link string for descripter
- call write_message ;write bottom message string to buffer
- db 'Choose route to terminate subchart',0
- jmp set_mode_2 ;write current route to stem string and
-
- ;terminate sub-chart link
-
- b1:
- mov ax,w box_save ;load subchart terminating box
- mov bx,w subchart_route ;load its route offset
- mov dx,w route ;copy route to it
- call store_box_par
- mov bp,w box_save ;make it current box
- xor ax,ax ;load zero
-
- ;clear variables
-
- mov w box_save,ax ;clear flag/main box
- mov w key_option,ax ;clear key option
- mov w insert_mode,ax ;clear mode
- cmp w terminating_route,0 ;is current box decision box?
- je >a1 ;exit if not
- mov bx,no ;load route element offset
- call get_current_box ;get current box pointer
- es cmp w[di+bx],0 ;is no route active?
- jne >a1 ;exit if it is
- es mov w[di+bx],1 ;indicate box is decision box
-
- ;clear bottom line message string and exit
-
- a1:
- mov b message,0 ;clear message string
- mov b chart_flag,4 ;set chart entry flag
- stc ;exit to chart loop
- ret
-
- ;link main box to link string
-
- create_link_string:
- cmp w box_to_subchart,0 ;is subchart being chosen?
- jne ret ;exit if it is
- mov di,o link_string ;load offset to link string
- mov es,ax,cs ;copy code segment
- mov al,26 ;load right arrow character
- stosb ;write it to end/start of link string
-
- ;copy any routes selected to end of link string
-
- mov si,o route_string ;load offset to routes selected string
- cmp b[si],0 ;is there a route string?
- je >a2 ;store link box if not
- mov ax,w[si+1] ;copy characters from route string
- xchg al,ah ;swap them as link string is in reverse
- stosw
- lodsb
- stosb
-
- ;copy link box number
-
- a2:
- mov ax,w link_box ;load link box
- sub ax,first_box-1 ;calculate its number
- call store_number2 ;convert it to string
- stosb ;end string
- ret ;exit
-
- ;copy subchart option
- ;get leading neighbour route to current box
-
- copy_subchart:
- call get_neighbour_route ;get route
- mov w route_to_subchart,bx ;save route
- or ax,ax ;is there a neighbour box?
- if e dec ax ;indicate no neighbour box if not
- mov w box_to_subchart,ax ;save neighbour box
- mov w box_save,bp ;set flag
- mov w subchart_link,bp ;save current box
- mov w link_box,bp ;store it as link box
- call write_message ;write bottom line message prompt
- db 'Choose a subchart to copy',0
- mov b chart_flag,1 ;set chart entry flag
- stc ;exit to chart loop
- ret
-
- ;write link box to bottom line
-
- view:
- mov ax,w link_box ;load link box
- cmp w key_option,1*2 ;is key option for link
- if be mov ax,w view_box ;load view box if it is
- call get_box_descripter ;get box descripter string pointer
-
- ;write box descripter to screen
-
- cmp cx,80 ;is string bigger than screen width?
- if a mov cx,80 ;load screen width if it is
- call clear_line ;clear bottom line(s)
- mov dx,80+24*256 ;load cursor coords
- sub dl,cl ;calculate column
- shr dl,1
- call cursor ;position cursor on bottom line
-
- ;copy string to screen
-
- a1:
- lodsb ;load character from string
- call write_chr ;write it to bottom line
- loop a1 ;decrement loop count
- mov ds,ax,cs ;restore data segment register
- e1:
- call key ;wait for keypress
- or ax,1 ;exit to middle of chart loop
- ret
-
- ;go to box option
-
- goto:
- call clear_line ;clear bottom lines
- call writexy ;write prompt to bottom line
- db 28,24
- db 'Please enter box number',0
- mov b s,0 ;clear number string buffer
-
- ;get input from user
-
- call get_string ;get box number
- dw s
- db 5,1
- jnc >a1 ;evaulate string if escape not pressed
- or bp,bp ;wait for next keypress
- ret ;exit to mid loop
-
- ;evaluate input
-
- a1:
- call get_val ;get box from user
- jc >b1 ;exit with error if not a number
- or dx,dx ;is number too big?
- jne >b1 ;exit with error if it is
- add ax,first_box-1 ;calculate box number
- cmp ax,w next_box ;is it valid box?
- jb >a1 ;check if box exists if it is
-
- ;write 'no such box' error message
-
- b1:
- call clear_line ;clear bottom line
- call writexy ;write error message
- db 34,24
- db 'No such box',0
- jmp e1 ;wait for keypress and exit
-
- ;check if box is active
-
- a1:
- mov bx,dx ;load previous box offset
- mov dx,ax ;save box
- call get_box_par ;get previous box
- cmp ax,-1 ;is box deleted?
- je b1 ;exit with error message if not
-
- ;make new box current box
-
- mov bp,dx ;load current box
- goto_box:
- mov w sub_stack,top_stack ;clear subchart stack
- mov b chart_flag,1 ;load chart entry flag
- cmp w box_save,0 ;is flowchart dormant?
- if e mov b chart_flag,4 ;store chart entry flag if not
- stc ;exit to start of chart loop
- ret
-
- ;search for specified string
-
- search:
- call clear_line ;clear bottom lines
- call writexy ;write prompt to bottom line
- db 27,24
- db 'Please enter search string',0
- call get_string ;get box number
- dw search_string
- db 128,1
- jnc >a1 ;check for upper case if escape not down
- or bp,bp ;don't exit to menu
- ret ;exit
-
- ;make search string upper case
-
- a1:
- mov dx,cx ;save size of string
- mov di,o search_string ;load pointer to start of string
- mov es,ax,cs
- a1:
- mov al,b[di] ;load char
- cmp al,'a' ;is it lower case?
- jb >a2 ;store it if not
- cmp al,'z' ;is it lower case?
- if be and al,05fh ;make it upper case if it is
-
- a2:
- stosb ;write char back
- loop a1 ;move to next character
- mov al,-1 ;terminate
-
- ;get pointer to first box
-
- mov ax,bp ;load id for box 1
- inc ax ;move to next box
- mov cx,w next_box ;calculate number of boxes to end chart
- sub cx,ax
- jbe >e2 ;exit if at end of chart
- call get_box ;get pointer
-
- ;check if box is active
-
- b1:
- es cmp w[di],-1 ;has box been deleted?
- je >b2 ;move to next box if not
- push ax,cx,dx,di,es ;save pointer to box
- es mov cx,w[di+descripter_length] ;load length of string
- sub cx,dx ;calculate number of compares
- jb >b3 ;move to next box if it is
- inc cx
-
- ;get pointer to box descripter
-
- es les ax,w[di+descripter] ;load address to descripter
- mov dx,es
- call get_pointer ;get pointer to string
- mov si,o search_string ;load offset to string
- a4:
- xor bx,bx ;clear sub offset
-
- ;load character from search string
-
- a1:
- es mov al,b[di+bx] ;load character from descripter
- cmp al,'a' ;is it lower case?
- jb >a2 ;compare with search string if it is
- cmp al,'z' ;is it lower case?
- if be and al,05fh ;make it upper case if it is
-
- ;compare characters
-
- a2:
- or al,al ;convert to zero?
- if e mov al,07fh ;substitute for marker
- cmp al,b[si+bx] ;do characters match?
- jne >a3 ;move to next start character
- inc bx ;move to next character in search string
- cmp b[si+bx],0 ;end of search string?
- jne a1 ;compare next character if not
-
- ;make box with found string current box
-
- pull es,di,dx,cx,ax ;restore registers
- mov bp,ax ;copy box with found string
- jmp goto_box ;change current box
- a3:
- inc di ;move to next character in descripter
- loop a4 ;reset sub offset
-
- ;move to next box
-
- b3:
- pull es,di,dx,cx,ax ;restore pointer to box records
- b2:
- call add_record ;move to next box
- inc ax ;increment box id
- loop b1 ;check if next box is active
-
- ;write 'no such box' error message
-
- e2:
- call clear_line ;clear bottom line
- call writexy ;write error message
- db 28,24
- db 'Search string not found',0
- jmp e1 ;wait for keypress and exit
-
- ;ammend box description option
-
- ammend:
- mov b chart_flag,4 ;set chart loop entry flag
- mov ax,bp ;load current box
- call get_box_descripter ;get pointer to its descripter string
- mov di,o s ;load offset to buffer
- mov es,ax,cs ;copy code segment
- mov bx,cx ;save size of string
- rep
- movsb ;copy string
- xor al,al ;load zero
- stosb ;end string
-
- ;edit string
-
- mov ds,ax,cs ;restore data segment register
- call get_string ;edit string
- dw s ;buffer for string
- db 128,0 ;maximum string size
-
- ;calculate size of block to move
-
- mov ax,w start_free_memory ;copy address to end of data
- mov w shift_count,ax
- mov ax,w start_free_memory+2
- mov w shift_count+2,ax
- push cx ;save new string length
-
- ;add old string size to pointer
-
- call get_current_box
- es mov ax,w[di+descripter] ;load descripter address
- es mov dx,w[di+descripter+2]
- call get_pointer ;convert it to pointer
- push di,es ;save pointer
- add ax,bx ;add size of initial string
- adc dx,0
- push ax,dx,bx,cx ;save string address and string sizes
- sub w shift_count,ax ;calculate size of data to move
- sbb w shift_count+2,dx
-
- ;check whether new string is bigger or smaller
-
- mov si,cx
- sub cx,bx ;is string bigger?
- jnc >b1 ;move data down if not
-
- ;shift descripter data down
-
- sub bx,si ;calculate margin
- mov si,ax
- mov di,ax ;calculate source address
- sub di,bx
- mov ax,dx
- sbb ax,0
-
- ;shift bytes down
-
- call address_segment ;convert high addresses to segment
- mov es,ax ;copy segment values
- mov ds,dx
- call shift_down ;shift data
- mov ds,ax,cs ;restore data segment
- jmp >c1 ;copy string
-
- ;calculate pointers
-
- b1:
- mov si,w start_free_memory ;load address to top of data
- mov ax,w start_free_memory+2
- mov di,si ;calculate destination pointer
- mov dx,ax
- add di,cx ;add margin
- adc dx,0
-
- ;shift bytes up
-
- call address_segment ;convert high address to segments
- mov es,dx ;copy segment values
- mov ds,ax
- call shift_up ;shift data
- mov ds,ax,cs ;restore data segment
-
- ;copy new string to store
-
- c1:
- pull ax,dx ;restore string sizes
- sub ax,dx ;calculate margin
- cwd ;sign extend it
- mov bx,ax ;save it
- mov si,dx
- pull dx,ax ;restore old descripter store address
- pull es,di,cx ;restore destination pointer and count
- push cx,si ;save high word of margin
- mov si,o s ;load source offset to new string
- rep
- movsb ;copy string
- pull si,cx ;restore margin high word
- mov b new_chart,0 ;indicate chart changed
- or bx,bx ;is there a change in memory size?
- stc ;exit to start of chart loop
- je ret ;exit if not
-
- ;update box descripter addresses
-
- call get_current_box ;get pointer to current box
- es mov w[di+descripter_length],cx ;store new descripter length
- update_descripters:
- push ax ;save address low word
- mov ax,first_box ;load first box
- call get_box ;get its pointer
- mov cx,w next_box ;load next box number
- sub cx,ax ;calculate number of boxes to check
- pull ax ;restore address
-
- ;compare address of start of shifted data with box descripter address
-
- a1:
- es cmp dx,w[di+descripter+2] ;is data above box string address
- ja >a2 ;decrement loop count if it is
- jb >a3 ;update address if not
- es cmp ax,w[di+descripter] ;is data above box string address
- ja >a2 ;decrement loop count if it is
-
- ;update box descripter address
-
- a3:
- es add w[di+descripter],bx ;add margin to address
- es adc w[di+descripter+2],si
- a2:
- call add_record ;move to next box
- loop a1 ;decrement loop count
- b1:
- add w start_free_memory,bx ;update ram top address
- adc w start_free_memory+2,si
- or ax,1 ;exit to middle of chart loop
- ret ;exit
-
- ;convert high words to segment format
-
- address_segment:
- shl ax,1
- shl dx,1
- shl ax,1
- shl dx,1
- shl ax,1
- shl dx,1
- shl ax,1
- shl dx,1
- shl ax,1
- shl dx,1
- shl ax,1
- shl dx,1
- shl ax,1
- shl dx,1
- shl ax,1
- shl dx,1
- shl ax,1
- shl dx,1
- shl ax,1
- shl dx,1
- shl ax,1
- shl dx,1
- shl ax,1
- shl dx,1
- ret ;exit
-
- ;create box and adjust pointers to descripter strings area
-
- make_box:
- push ax,bx,cx,dx,si ;save registers
- mov si,w start_free_memory ;load address to top of data
- mov w shift_count,si ;save it
- mov bx,w start_free_memory+2
- mov w shift_count+2,bx
- mov ax,w next_box ;load new box
- call get_box_address ;get box address in ax:dx
- push ax,dx ;save it
- sub w shift_count,ax ;calculate number of bytes to shift
- sbb w shift_count+2,dx
-
- ;calculate pointers for descripter string area shift
-
- mov di,si ;load offset to end of data
- mov cx,bx ;load segment
- add di,box_record ;add box record size
- adc cx,0
-
- ;convert segment words to segment format
-
- mov ax,cx
- mov cl,12
- shl ax,cl
- shl bx,cl
-
- ;shift descripter string area
-
- mov es,ax ;load segments
- mov ds,bx
- call shift_up ;shift bytes
- mov ds,ax,cs ;restore data segment register
-
- ;update all boxes addresses to their descripters
-
- mov ax,w chart ;load address to start of boxes
- mov dx,w chart+2
- call get_pointer ;convert it to pointer
- mov cx,w next_box ;calculate number of boxes in memory
- sub cx,first_box
- pull dx,ax ;restore address of box
- jcxz >a2 ;clear record if no other boxes
- a1:
- es add w[di+descripter],box_record ;add record size to address
- es adc w[di+descripter+2],0
- call add_record ;move to next box record
- loop a1 ;decrement loop count
-
- ;clear new box
-
- call get_pointer ;convert it to pointer
- a2:
- push di ;save offset
- xor ax,ax ;load zero
- mov cx,descripter/2 ;load element count
- rep
- stosw ;clear record
-
- ;copy address of box descripter
-
- add w start_free_memory,box_record ;move address to end of data
- adc w start_free_memory+2,0
- mov ax,w start_free_memory ;copy address to top of memory
- stosw
- mov ax,w start_free_memory+2
- stosw
-
- ;exit
-
- pull di,si,dx,cx,bx,ax ;restore registers
- ret ;exit
-
- ;shift text up
- ;entry:
- ;number of bytes to shift in 32 bit store shift_count
- ;ds:si source pointer
- ;es:di destination pointer
-
- shift_up:
- dec si,si,di,di ;move back over last word
- std ;set direction flag for moving down
- b1:
- call load_count ;load count of bytes to move
- xor ax,ax ;exit if finished
- jcxz >c1
-
- ;range check pointers
-
- cmp di,cx ;is there enough space below?
- ja >a1 ;convert count if there is
- mov dx,cx ;load maximum size needed
- sub dx,di ;calculate neccessary margin
- add dx,010h ;add a paragraph
- and dx,0fff0h ;mask out loose bytes
- add di,dx ;add margin to offset
- shr dx,1 ;convert to segment
- shr dx,1
- shr dx,1
- shr dx,1
- mov ax,es ;load segment
- sub ax,dx ;adjust it
- mov es,ax
-
- ;adjust source pointer if not enough room for transfer
-
- a1:
- cmp si,cx ;is there enough space below?
- ja >a1 ;exit if there is
- mov dx,cx ;load maximum size needed
- sub dx,si ;calculate neccessary margin
- add dx,010h ;add a paragraph
- and dx,0fff0h ;mask out loose bytes
- add si,dx ;add margin to offset
- shr dx,1 ;convert to segment
- shr dx,1
- shr dx,1
- shr dx,1
- mov ax,ds ;load segment
- sub ax,dx ;adjust it
- mov ds,ax
-
- ;copy data
-
- a1:
- mov ax,cx ;load shift count
- shr cx,1 ;half it
- rep
- movsw
- test ax,1 ;is shift count odd?
- je b1 ;load count for next batch if not
- inc si,di ;increment offsets
- movsb ;move byte
- jmp b1 ;load count
- c1:
- cld ;restore direction flag
- ret ;exit
-
- ;shift text down
- ;number of bytes to shift in 32 bit store shift_count
- ;ds:si source pointer
- ;es:di destination pointer
- ;adjust destination pointer if not enough room for transfer
-
- shift_down:
- call load_count ;load count of bytes to move
- xor ax,ax ;exit if finished
- jcxz ret
- call range_check_pointers ;range check both pointers
- mov ax,cx ;load shift count
- shr cx,1 ;half it
- rep
- movsw
- test ax,1 ;is shift count odd?
- je shift_down ;get count for next batch if not
- movsb ;move byte
- jmp shift_down ;move them if yes
-
- ;check if there is enough space above destination index register
-
- range_check_sptr:
- mov ax,si ;calculate amount of space above
- not ax ;pointer
- cmp ax,cx ;is there enough space above?
- jae ret ;exit if there is
- push bx ;save register
- mov bx,cx ;load maximum size needed
- sub bx,ax ;calculate neccessary margin
- add bx,010h ;add a paragraph
- and bx,0fff0h ;clear low nybble
- sub si,bx ;add margin to offset
- shr bx,1 ;convert to segment
- shr bx,1
- shr bx,1
- shr bx,1
- mov ax,ds ;load segment
- add ax,bx ;adjust it
- mov ds,ax
- pull bx ;restore register
- ret ;exit
-
- ;range check destination pointer
-
- range_check_pointers:
- call range_check_sptr ;range check source pointer
-
- ;range check destination pointer (es:di)
-
- range_check_dptr:
- mov ax,di ;calculate amount of space above
- not ax ;pointer
- cmp ax,cx ;is there enough space above?
- jae ret ;exit if there is
- push bx ;save register
- mov bx,cx ;load maximum size needed
- sub bx,ax ;calculate neccessary margin
- add bx,010h ;add a paragraph
- and bx,0fff0h ;clear low nybble
- sub di,bx ;add margin to offset
- shr bx,1 ;convert to segment
- shr bx,1
- shr bx,1
- shr bx,1
- mov ax,es ;load segment
- add ax,bx ;adjust it
- mov es,ax
- pull bx ;restore register
- ret ;exit
-
- ;load cx with maximum count
-
- load_count:
- mov cx,0ffceh ;load maximum shift count
- cs cmp w shift_count+2,0 ;is shift count greater than a segment?
- ja >a1 ;exit if it is
- cs cmp w shift_count,0ffeeh ;is count greater?
- ja >a1 ;exit if not
- cs mov cx,w shift_count ;load rest of bytes to shift
-
- ;subtract size of block from count
-
- a1:
- cs sub w shift_count,cx ;subtract sub count from count
- cs sbb w shift_count+2,0
- ret ;exit
-
- ;add box record to pointer ds:si
-
- add_record2:
- cmp si,-box_record*4 ;is there enough room to add a record?
- jb >a1 ;add it if there is
- sub si,08000h ;make enough room in offset
- push ax ;save register
- mov ax,ds ;adjust segment
- add ax,0800h
- mov ds,ax
- pull ax ;restore register
- a1:
- add si,box_record ;move to next record
-
- ;add box record to pointer es:di
-
- add_record:
- cmp di,-box_record*4 ;is there enough room to add a record?
- jb >a1 ;add it if there is
- sub di,08000h ;make enough room in offset
- push ax ;save register
- mov ax,es ;adjust segment
- add ax,0800h
- mov es,ax
- pull ax ;restore register
- a1:
- add di,box_record ;move to next record
- ret ;exit
-
- ;return box pointer in es:di
-
- get_current_box:
- push ax ;save register
- mov ax,bp ;load current box
- jmp >a1 ;get its pointer
- get_box:
- push ax ;save register
- a1:
- push bx,cx,dx ;save registers
- call get_box_address ;get pointer to box
- call get_pointer
- pull dx,cx,bx,ax ;restore registers
- ret ;exit
-
- ;calculate box offset
-
- get_box_address:
- push bx,cx ;save registers
- sub ax,first_box ;calculate box number
- cwd ;sign extend it
- shl ax,1 ;x 2
- rcl dx,1
- mov bx,ax ;save it
- mov cx,dx
- shl ax,1 ;x 4
- rcl dx,1
- shl ax,1 ;x 8
- rcl dx,1
- shl ax,1 ;x 16
- rcl dx,1
- add ax,bx ;X18
- adc dx,cx
- add ax,w chart ;add it to start of box records address
- adc dx,w chart+2
- pull cx,bx ;restore registers
- ret ;exit
-
- ;get pointer to top of ram
-
- get_pointer2:
- mov ax,w start_free_memory ;load address to top of data
- mov dx,w start_free_memory+2
-
- ;convert high word to segment format
-
- get_pointer:
- push ax,dx ;save registers
- shl dx,1 ;move segment nybble to top end
- shl dx,1
- shl dx,1
- shl dx,1
- shl dx,1
- shl dx,1
- shl dx,1
- shl dx,1
- shl dx,1
- shl dx,1
- shl dx,1
- shl dx,1
-
- ;return pointer in es:di
-
- mov es,dx ;load segment
- mov di,ax ;load offset
- cmp di,-(box_record*4) ;is there enough room in offset?
- jb >a1 ;exit if there is
- sub di,08000h ;subtract a page
- mov ax,es ;adjust segment
- add ax,0800h
- mov es,ax
- a1:
- pull dx,ax ;restore registers
- ret ;exit
-
- ;return box parameter
-
- get_current_box_par:
- xor ax,ax ;load zero
- or bp,bp ;is there a current box?
- je ret ;exit if not
- mov ax,bp ;load current box
- get_box_par:
- or ax,ax ;is box valid?
- je ret ;exit if not
- push di,es ;save pointer
- call get_box ;get pointer to box
- es mov ax,w[di+bx] ;get parameter from box record
- pull es,di ;restore pointer
- ret ;exit
-
- ;store box parameter
-
- store_current_box_par:
- xchg ax,bp ;load current box
- call store_box_par ;store box parameter
- xchg ax,bp ;restore register
- ret ;exit
-
- ;store box parameter
-
- store_box_par:
- push di,es ;save pointer
- call get_box ;get pointer to box
- es mov w[di+bx],dx ;store parameter to box record
- pull es,di ;restore pointer
- ret ;exit
-
- ;get pointer to box descripter
-
- get_box_descripter:
- push dx,di,es ;save pointer
- call get_box ;get box pointer
- es mov cx,w[di+descripter_length] ;load string size
- es les si,w[di+descripter] ;load pointer to descripter string
-
- ;convert segment word to segment format
-
- mov dx,es ;load segment word
- shl dx,1
- shl dx,1
- shl dx,1
- shl dx,1
- shl dx,1
- shl dx,1
- shl dx,1
- shl dx,1
- shl dx,1
- shl dx,1
- shl dx,1
- shl dx,1
- cmp si,0ff80h ;is there enough room in string for copy
- jb >a1 ;exit if there is
- sub si,0100h ;subtract a page from pointer
- add dx,010h
- a1:
- mov ds,dx ;store segment of pointer
- pull es,di,dx ;restore pointer
- ret ;exit
-
- ;read value from configuration file
-
- get_val:
- jcxz >c1 ;exit if error
- b1:
- lodsb ;load character from file
-
- ;check if next character is numeric
-
- dec si ;move offset over first character
- mov bx,si ;save offset to line
- a1:
- jcxz >a2 ;convert ascii digits to number
- lodsb ;load character from line
- dec cx
- cmp al,'0' ;is character below ascii 0?
- jb >c1 ;exit if it is
- cmp al,'9' ;is character above ascii 9?
- jbe a1 ;get next character if not
-
- ;exit indicating error
-
- c1:
- stc ;indicate error
- ret ;exit
-
- ;check if last character is carriage return
-
- a2:
- push cx,si ;save file count and offset
- mov cx,si ;load offset to end of number
- sub cx,bx ;calculate length of string
- mov w temp1,1 ;store multiplier
- mov w temp1+2,0
- mov w temp3,0 ;clear return value
- mov w temp3+2,0
- dec si ;move offset over last digit
- std ;set direction flag
-
- ;get digit
-
- a1:
- lodsb ;load digit from configuration file
- sub al,'0' ;take away base
- xor ah,ah ;clear high register
- xor bx,bx ;load product
- xor dx,dx
- push cx ;save count
- mov cx,16 ;load bit count
-
- ;mulitply digit by ten base
-
- a2:
- shl bx,1 ;multiply product by 2
- rcl dx,1
- shl ax,1 ;shift multiplier left one
- jnc >a3 ;decrement loop count if no carry
- add bx,w temp1 ;add multiplicand to product
- adc dx,w temp1+2
- a3:
- loop a2 ;decrement loop count
- add w temp3,bx ;add product to return value
- adc w temp3+2,dx
-
- ;mulitiply multiplicand by ten
-
- mov ax,w temp1 ;load it
- mov dx,w temp1+2
- shl ax,1 ;multiply it by 4
- rcl dx,1
- shl ax,1
- rcl dx,1
- add ax,w temp1 ;add it by one
- adc dx,w temp1+2
- shl ax,1 ;multiply it by 2
- rcl dx,1
- mov w temp1,ax ;store it
- mov w temp1+2,dx
- pull cx ;restore outer loop count
- loop a1 ;fetch next character
- cld ;restore direction flag
-
- ;exit with value read in ax:dx
-
- mov ax,w temp3 ;load value read
- mov dx,w temp3+2
- pull si,cx ;restore offset and file count
- clc ;indicate ok
- ret ;exit
-
- ;clear screen
-
- cls:
- cs cmp b direct_video,0 ;is screen output direct?
- jne >a1 ;clear screen direct if it is
- mov ax,0600h ;load function parameters
- mov bh,7 ;load attribute
- xor cx,cx ;load top left corner coordinates
- mov dx,0184fh ;load bottom right corner coordinates
- call int10 ;clear the screen
- ret ;exit
-
- ;clear screen
-
- a1:
- xor dx,dx ;move cursor to top left of screen
- call cursor ;position cursor
- mov ax,0720h ;load space and attribute
- mov cx,80*25
- cs les di,w video_pointer ;load pointer to start of map
- rep
- stosw
- mov es,ax,cs ;copy segment to workspace
- ret ;exit
-
- ;get keypress
-
- key:
- mov ah,01h ;load keyboard function parameter
- int 016h ;scan keyboard
- jne >a1 ;exit if key down
- cs cmp b middle_5,0 ;is middle 5 on numeric keypad down?
- je key ;scan keyboard if not
-
- ;only exit if chart is dormant
-
- cmp w box_save,0 ;is flowchart dormant?
- je >b1 ;exit if it is
- cs mov b middle_5,0 ;clear flag
- jmp key ;wait for next keypress
- b1:
- stc ;indicate key down
- ret ;exit
-
- ;get keypress
-
- a1:
- xor ah,ah ;fetch the key
- int 016h
- cmp ax,011b ;exit with zero set if key is escape
- clc ;indicate middle 5 not down
- ret ;exit
-
- ;end